package tgc.edu.ljc.web.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import tgc.edu.ljc.custom.AjaxResult;
import tgc.edu.ljc.entity.SysDept;
import tgc.edu.ljc.entity.SysFile;
import tgc.edu.ljc.entity.SysUser;
import tgc.edu.ljc.service.DataSumService;
import tgc.edu.ljc.service.SysFileService;
import tgc.edu.ljc.service.SysUserService;
import tgc.edu.ljc.web.form.SysFileForm;

@Controller
@RequestMapping(value="/app")
@CrossOrigin
/***
 * 移动端控制器
 * @author ljc
 *
 */
public class AppController {
	
	@Autowired
	private DataSumService dataSumService;
	@Autowired
	private SysFileService service;
	
	@Autowired
	private SysUserService userService;
	
	//private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
	@RequestMapping(value="/login")
	@ResponseBody
	/***
	 * 登录
	 * @param username 用户名
	 * @param pwd 密码
	 * @return 
	 ***/
	public Object login(String username,String pwd,HttpServletRequest request,HttpServletResponse response) {
		/*response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
		response.setHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("P3P", "CP=CAO PSA OUR");
		if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
		    response.addHeader("Access-Control-Allow-Methods", "POST,GET,TRACE,OPTIONS");
		    response.addHeader("Access-Control-Allow-Headers", "Content-Type,Origin,Accept");
		    response.addHeader("Access-Control-Max-Age", "120");
		}*/
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		Map<String, Object> result=new HashMap<>();
		username=username.trim();
		SysUser user = userService.findByUsername(username);
		if(user==null) {
			result.put("ok", false);
			result.put("msg","用户名或密码错误");
			return result;
		}
		String password = user.getPassword();
		
		boolean flag = encoder.matches(pwd.trim(), password);
		String deptStr="";
		SysDept dept = user.getDept();
		while(dept!=null) {
			deptStr="/"+dept.getName()+deptStr;
			dept=dept.getParent();
		}
		deptStr=deptStr.substring(1);
		if(flag) {
			result.put("ok",true);
			result.put("username", username);
			result.put("name",user.getName());
			result.put("deptName",deptStr);
			result.put("roles", user.getRoleCodes().split(","));
			result.put("msg","登录成功");
		}else {
			result.put("ok", false);
			result.put("msg","用户名或密码错误");
		}
		return result;
	}
	
	@RequestMapping(value="/swiper")
	@ResponseBody
	/***
	 * 取app 主页的轮播图
	 * @return 三个随机图片的文件记录
	 */
	public Object swiper() {
		Specification<SysFile> spec=new Specification<SysFile>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<SysFile> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate>rules=new HashSet<>();
				rules.add(cb.equal(root.get("fileType").get("code"), "DICT_FILETYPE_PICTURE"));
				rules.add(cb.equal(root.get("fileNature").get("code"), "DICT_PUBLIC"));
				rules.add(cb.isTrue(root.get("isUsed")));
				return cb.and(rules.toArray(new Predicate[rules.size()]) );
			}
		};
		List<SysFile> list = service.findAll(spec);
		List<SysFile> result=new ArrayList<>();
		for(int i=0;i<3;i++) {
			int n=(int) (Math.random()*list.size());
			result.add(list.get(n));
		}
		return result;
	}
	
	@RequestMapping(value="/findSysFileById")
	@ResponseBody
	public Object findBySysFileId(Integer id) {
		if(id==null) {
			return null;
		}
		SysFile result = service.findById(id);
		return result;
	}
	
	
	@RequestMapping(value="/findFileNatures")
	@ResponseBody
	public Object findFileNatures() {
		return dataSumService.findFileNatures();
	}
	
	@RequestMapping(value="/findFileTypes")
	@ResponseBody
	public Object findFileTypes() {
		return dataSumService.findFileTypes();
	}
	
	/***
	 * 编辑页面要的数据
	 * @param id 要编辑的sysFile记录的id
	 * @return sysFile,fileNatures,fileTypes
	 */
	@RequestMapping(value="/edit")
	@ResponseBody
	public Object edit(Integer id) {
		HashMap<String, Object> result=new HashMap<>();
		Object sysFile;
		if(id==null) {
			sysFile=new SysFile();
		}else {
			sysFile= findBySysFileId(id);
		}
		Object fileNatures = findFileNatures();
		Object fileTypes = findFileTypes();
		result.put("sysFile", sysFile);
		result.put("fileNatures",fileNatures);
		result.put("fileTypes", fileTypes);
		return result;
	}
	
	@RequestMapping(value="/save2")
	@ResponseBody
	public Object saveTest(SysFileForm form,String userName ) {
		MultipartFile file = form.getFile();
		MultipartFile[] file2 = form.getFile2();
		System.out.println("userName:"+userName);
		System.out.println("fileType:"+form.getFileType());
		if(file!=null) {
			System.out.println(file.getOriginalFilename());
		}
		if(file2!=null) {
			for (MultipartFile mf : file2) {
				System.out.println(mf.getOriginalFilename());
			}
		}
		return new AjaxResult("ok");
	}
	
	@RequestMapping(value="/save")
	@ResponseBody
	public Object save(SysFileForm form,String userName,String pwd) {
		boolean savefile = true;
		SysUser user = isLogin(userName, pwd);
		if(user==null) {
			return new AjaxResult(false, "你没有上传资源文件的权限!");
		}
		List<String> filenames = new ArrayList<>();
		if (form.getId() == null) {
			for (MultipartFile file : form.getFile2()) {
				form.setFile(file);
				form.setFileUser(userName);
				boolean savefile2 = service.savefile(form);
				if(!savefile2) {
					savefile=false;
					filenames.add(file.getOriginalFilename());
				}
			}
			if (savefile) {
				return new AjaxResult("文件上传成功");
			} else {
				return new AjaxResult(false,filenames.toString()+ "文件上传失败");
			}
		} else {
			SysFile findById = service.findById(form.getId());
			if (!user.hasManagerRole() && !user.getUsername().equals(findById.getUploadsUsername())) {
				return new AjaxResult(false, "修改失败，您没有修改该文件的权限！");
			}
			service.mySave(findById, form);
			return new AjaxResult("保存成功");
		}
		
	}
	
	/***
	 * 将文件移入回收站
	 * @param id
	 * @return
	 ***/
	@RequestMapping(value="/delete")
	@ResponseBody
	public Object delete(Integer id,String userName,String pwd) {
		SysUser user = isLogin(userName, pwd);
		if(user==null) {
			return new AjaxResult(false, "你没有删除此文件的权限");
		}
		SysFile sysFile = service.findById(id);
		if(!user.hasManagerRole() && !userName.equals(sysFile.getUploadsUsername())) {
			return new AjaxResult(false,"你没有删除此文件的权限");
		}
		if(sysFile!=null) {
			sysFile.setIsUsed(false);
			service.save(sysFile);
			return new AjaxResult("删除成功");
		}
		return new AjaxResult(false, "该文件没有找到");
	}
	
	/***
	 * 用户合法判断
	 * @param userName
	 * @param pwd
	 * @return 合法，返回用户对象，不合法返回null
	 */
	private SysUser isLogin(String userName,String pwd) {
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		SysUser user = userService.findByUsername(userName);
		if(user==null) {
			return null;
		}
		String password = user.getPassword();
		if(encoder.matches(pwd, password)) {
			return user;
		}
		return null;
	}
	
	private HashMap<String, Object> errorResult(){
		HashMap<String, Object> result=new HashMap<>();
		result.put("isGuest",true);
		result.put("msg", "你不是一个合法用户，不能进行此项操作！");
		return result;
	}
	
	@RequestMapping(value="/h5Upload")
	public String h5Upload( Integer id, ModelMap modelMap) {
		if(id==null) {
			SysFile model = new SysFile();
			modelMap.put("edit", false);
			modelMap.put("model", model);
		}else {
			modelMap.put("edit",true);
			modelMap.put("sysFile", findBySysFileId(id));
			modelMap.put("model", findBySysFileId(id));
		}
		modelMap.put("fileNatures", findFileNatures());
		modelMap.put("fileNature", findFileNatures());
		modelMap.put("fileTypes", findFileTypes());
		modelMap.put("fileType", findFileTypes());
		//return "app/h5Upload";
		return "app/edit";
	}
	
	@RequestMapping(value="/findDeletedList")
	@ResponseBody
	public List<SysFile> findDeletedList(String userName) {
		Specification<SysFile> spec=buildDeletedList(userName);
		Sort sort=Sort.by(Direction.DESC, "updateTime");
		return service.findAll(spec, sort);
	}
	
	private Specification<SysFile> buildDeletedList(String userName) {
		Specification<SysFile> spec1=new Specification<SysFile>() {
			private static final long serialVersionUID = 1L;
			@Override
			public Predicate toPredicate(Root<SysFile> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.isFalse(root.get("isUsed"));
			}
		};
		Specification<SysFile> spec2=new Specification<SysFile>() {
			private static final long serialVersionUID = 2L;
			@Override
			public Predicate toPredicate(Root<SysFile> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.equal(root.get("uploadsUsername"), userName);
			}
		};
		return spec1.and(spec2);
	}
	
	/***
	 * 将回收站的文件恢复
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/restore")
	@ResponseBody
	public Object restore(Integer id) {
		SysFile model = service.findById(id);
		if(model!=null) {
			model.setIsUsed(true);
			service.save(model);
			return new AjaxResult("文件恢复成功");
		}else {
			return new AjaxResult(false, "文件没有找到！！");
		}
	}
	
	@RequestMapping(value="/remove")
	@ResponseBody
	public Object remove(Integer id,String userName) {
		SysFile model = service.findById(id);
		if(!StringUtils.hasText(userName)||!userName.equals(model.getUploadsUsername())) {
			return new AjaxResult(false, "你没有该文件的删除权限！");
		}
		service.deleteFile(id);
		return new AjaxResult("文件删除成功！");
	}
	
	@RequestMapping(value="/removeAll")
	@ResponseBody
	public Object removeAll(String userName) {
		try {
			List<SysFile> list = findDeletedList(userName);
			for (SysFile sysFile : list) {
				service.deleteFile(sysFile.getId());
			}
			return new AjaxResult("回收站已清空！");
		}catch (Exception e) {
			return new AjaxResult(false, "清空回收站失败！");
		}
	}
	
	/***
	 * 修改密码
	 * @param userName 用户名
	 * @param newPwd  新密码
	 * @param oldPwd  旧密码
	 * @return
	 */
	@RequestMapping(value="/changePwd")
	@ResponseBody
	public Object changePwd(String userName,String newPwd,String oldPwd) {
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		SysUser user = userService.findByUsername(userName);
		if(user==null) {
			return new AjaxResult(false, "用户不存在！");
		}
		if(!encoder.matches(oldPwd, user.getPassword())) {
			return new AjaxResult(false,"旧密码错误");
		}
		user.setPassword(encoder.encode(newPwd));
		userService.save(user);
		return new AjaxResult("密码修改成功");
	}
	
}
